﻿using AspectCore.DependencyInjection;
using AspectCore.DynamicProxy;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Common
{
    public class CustomInterceptorAttribute : AbstractInterceptorAttribute
    {

        #region 属性注入
        //属性注入，在拦截器中拥有public get and set权限的属性标记[AspectCore.DependencyInjection.FromServiceContextAttribute]特性，即可自动注入该属性
        //[FromServiceContext]
        //public IHttpContextAccessor accessor { get; set; }
        #endregion

        #region 构造函数注入
        private readonly ILogger<CustomInterceptorAttribute> ctorlogger;

        private IHttpContextAccessor _assessor;

        // ps : 当全局配置 config.Interceptors.AddTyped<CustomInterceptorAttribute>(); 时，构造器注入无法自动注入，需要手动处理
        //      只有使用 services.AddSingleton<CustomInterceptorAttribute>(); + services.ConfigureDynamicProxy(config => { config.Interceptors.AddServiced<CustomInterceptorAttribute>(); }); 才会自动注入
        public CustomInterceptorAttribute(IHttpContextAccessor assessor, ILogger<CustomInterceptorAttribute> ctorlogger)
        {
            _assessor = assessor;
            this.ctorlogger = ctorlogger;
        }
        #endregion


        public async override Task Invoke(AspectContext context, AspectDelegate next)
        {
            //服务定位器模式
            //IHttpContextAccessor _accessor = context.ServiceProvider.GetRequiredService<IHttpContextAccessor>();
            string path= _assessor.HttpContext.Request.Path.Value;

            dynamic par = context.Parameters[0];

            if (par != null)
            {
                Console.WriteLine(par.Id);
                Console.WriteLine(par.Name);
                Console.WriteLine(par.Age);
                Console.WriteLine(par.time);
            }

            try
            {
                Console.WriteLine("Before service call");
                await next(context);

                dynamic returnValue = context.ReturnValue;
                if (returnValue != null)
                {
                    Console.WriteLine(returnValue.Before);
                    Console.WriteLine(returnValue.After);
                    Console.WriteLine(returnValue.Msg);
                    Console.WriteLine(returnValue.CreateTime);
                }


            }
            catch (Exception)
            {
                Console.WriteLine("Service threw an exception!");
                throw;
            }
            finally
            {
                Console.WriteLine("After service call");
            }
        }
    }
}
